#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp> 
#include <boost/functional/factory.hpp>
#include <boost/function.hpp>
#include <boost/unordered_map.hpp>

using namespace std;

class A : public boost::enable_shared_from_this<A>
{
public:
	A() { cout << "A()" << endl; }
	virtual ~A() { cout << "~A()" << endl; }
};

class C
{
public:
	C() : a_(new A) { cout << "C()" << endl; }
	virtual ~C() { cout << "~C()" << endl; 	}
protected:
	boost::shared_ptr<A> a_;
};

class Base : public boost::enable_shared_from_this<Base>
{
public:
	Base() { cout << "Base()" << endl; }
	virtual ~Base() { cout << "~Base()" << endl; }
	virtual void print() { cout << "Base::print()" << endl; }
};

class Inherit : public Base
{
public:
	Inherit() { cout << "Inherit()" << endl; }
	virtual ~Inherit() { cout << "~Inherit()" << endl; }
	virtual void print() { cout << "Inherit::print()" << endl; }
	boost::shared_ptr<Inherit> get_ptr() { return boost::dynamic_pointer_cast<Inherit>(shared_from_this()); }
};

int main()
{
	{
		cout << "Test 1" << endl;
		C* c = new C();
		delete c;
	}

	{
		cout << "Test 2" << endl;
		Base* b = new Inherit();
		delete b;
	}

	{
		cout << "Test 3" << endl;
		boost::shared_ptr<Base> i(new Inherit());
		i->print();
		boost::shared_ptr<Inherit> d = boost::dynamic_pointer_cast<Inherit>(i)->get_ptr();
		d->print();
	}

	{
		cout << "Test 4" << endl;
		typedef boost::function<Base*(void)> a_factory;
		boost::unordered_map<std::string, a_factory> factories;
		a_factory f = boost::factory<Inherit*>();
		factories["Inherit"] = f;
		boost::shared_ptr<Base> a(factories["Inherit"]());
		a->print();
		boost::shared_ptr<Inherit> b = boost::dynamic_pointer_cast<Inherit>(a)->get_ptr();
		b->print();	
	}


	return 0;
}

